#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>        
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <libgen.h>
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h> 
#include <sys/time.h>


#include "sample.h"
#include "sqlite3.h"
#include "logger.h"
#include "semaphore.h"
#include "database.h"

#include "com_server.h"

int g_stop = 0;
void sig_stop(int signum)
{
	if(SIGUSR1 == signum)
	{
		g_stop = 1;
	}
}



static inline void print_usage(char *progname)
{
	printf("Usage:%s [option]...\n", progname);

        printf("%s is a socket server program, which used to verify client and echo back string from it\n", progname);
	printf("\n Mandatory arguments to long options are mandatory for short options too:\n");

        printf("-b(daemon)set progname runing on background\n");
	printf("-p(--port):sepcify server listen port.\n");
	printf("-i(--servip):sepcify server address.\n");
	printf("-s(--sleep_time):sepcify sleep time to send data.\n");
	printf("-h(--hellp):print this help information.\n");

	printf("\n Example:%s -b -i 127.0.0.1  -p 8900 -s 30\n", progname);
	return ;

}
int main (int argc, char **argv)
{
	int                    port;
	int                    sleep_time;
	char                   data_buff[1024];
	int                    sockfd = -1;
        int                    daemon_run = 0;
        char                  *progname = NULL;
        int                    opt = -1;
        char                  *servip=NULL;
	char                   tbuff[64];
	char                  *ID_count=NULL;
	struct sockaddr_in     servaddr;
	int                    i;

	st_data                sample_data;
	st_data                db_data;
	sqlite3               *db;
	int                    sample_flag;
	int                    data_flag;
	int                    last_time;
	int                    now_time;


 
 
struct option                    long_options[] = 
{
	{"dameon", no_argument, NULL, 'b'},
	{"port", required_argument, NULL, 'p'},
	{"sleep_time", required_argument, NULL, 't'},
	{"servip", required_argument, NULL, 'i'},
	{"SN", required_argument, NULL, 's'},
	{"help", no_argument, NULL, 'h'},
	{ NULL, 0, NULL, 0}
};
progname = basename(argv[0]);


while((opt = getopt_long(argc, argv,"bi:p:s:t:h", long_options, NULL)) != -1)//(需要参数再加:)
{
	switch(opt)
	{
		case 'b':
			daemon_run=1;
			break;

		case 'i':
			servip=optarg;
			break;
	        case 's':
			ID_count=optarg;
			break;

		case 'p':
			port=atoi(optarg);//将冒号后的字符串参数转换为整型赋值给port
			break;
		case 't':
			sleep_time=atoi(optarg);
			break;
                                  
		case 'h':
			print_usage(progname);
			break;

		default:
			break;
	}

}

if( !port||!servip )
{
	print_usage(progname);
	return -1;
}
/*定义日志系统*/
/* 标准输出只打印出错信息*/
if(logger_init("stdout", LOG_LEVEL_INFO) <0)
{
        fprintf(stderr, "inital logger system failure\n");	
	return -1;
}
/*开始循环前先打开数据库把表创建好，结束循环再关闭表，可以节省内存*/

signal(SIGUSR1,  sig_stop);//安装信号

if(database_open(&db, "temp_data.db")!=0)
{
	log_error("cannot open database\n");  
	return -1;
}


#if 0
	last_time = 0;

	while ( ! g_stop )
	{
		/* 1. 看采样时间到了没，如果到了就采样 */
		now_time = time(NULL);
		sample_flag = 0;

		if( now - last_time >= 30 )
		{
			sample_data();
			sample_flag = 1;
			last_time = now_time;
		}

		/* 2. 判断socket是否断开，如果断开就要重连 */
		if( sockfd < 0) 
		{
			socket_connect();
		}


		/* 3. 如果socket 连接失败 */
		if( sockfd<0 && sample_flag )
		{
			save_to_db();
		}

		/* 4. 如果socket 连接成功 */
		if( socket >= 0 )
		{
			if( 有数据)
			   发送数据库里的数据

			if( 有采样)
			   发送实时采样的数据;
		}


		sleep(1);
	}
#endif

	last_time = time(NULL);//获取当前时间


	while ( !g_stop)
	{
		now_time=time(NULL);
		sample_flag = 0;//采样标志
		if((now_time - last_time)>sleep_time)
		{
                /*采样温度 */
			printf("start sampling!\n");
			/* sample_data初始化*/
			if (get_temp(&sample_data.temp) != 0)
			{
				log_error("get temperature failure !: %s\n", strerror(errno));
				return -3;
			}
        		get_time( sample_data.time );//获取时间,传buff传大小
	        	strncpy( sample_data.sn, ID_count, sizeof(sample_data.sn));
	        	sample_flag = 1;
			last_time = now_time;
		}
/*定时采样正常进行。在此期间所有采样的数据临时存储到 SQLite数据库中*/       
/*判断，如果没有连上服务器上报日志，如果连上服务器则将已经存储到数据库中的数据发送给服务器端*/
		if (sockfd  < 0)//listenfd 没连上服务器
		{
                        log_info("start connecting  server...\n");
		        if ( (sockfd = socket_client_init(servip, port)) < 0)//连接失败，将采样的数据上传数据库
		        {
			         log_error("connect to server failure!\n");
				 socket_close(&sockfd);
				 if( sample_flag )//如果采样成功采样则上传数据库
				 {
					 if( database_insert_data( db, &sample_data) != 0)//断网时将采样的数据存放在数据库
					 {
						 log_error("database_insert_data() failure\n");
						 return -4;
					 }
					 log_info("Data has been saved to the database when the network is disconnected!\n");
				 }
		        }
		}
		else if(sockfd >0)//已近连上服务器
		{
	/*网络故障恢复之后，客户端程序自动将之前暂存到数据库中的数据上报到服务器上去，并从里面删除*/
			log_info("connect with server successfully!\n");

				        /* db_data里有值则发送 */
			if ((data_flag = database_get_id(db)) > 0)
			{
				log_info("start to send data to server from database!\n");
				if (database_query_data(db, &db_data) < 0)//将断网时存储在数据库的数据拿初始化db_data
				{
					log_error("database_query_data() failure!\n");
					continue;
				}

				if (socket_send_data(sockfd, &db_data)!=0)
				{
					log_error("sqlite_selecet() failure!\n");
					continue;
				}
				else if(database_delete_data(db)!=0)
				{
					log_error("delete database failure\n");
					continue;
				}
			}

			/*实时采样*/
			if( sample_flag )
			{
				if( socket_send_data(sockfd, &sample_data) < 0)
				{
	/*如果发送数据失败，则关闭sockfd，然后将sockfd的值设为负值，让他返回sockfd<0，重新连接，并将采样到的值保存在数据库里*/
				        socket_close(&sockfd);
					sockfd = -1;
					database_insert_data(db, &sample_data);
				}
				log_info("sucess to send data:%s\n", data_buff);
			}
		}
         	sleep(1);//采样时间
		log_info("started next sample !\n");
		printf("-------------------------------------------------\n");

	}
        socket_close(&sockfd);
        logger_term();//结束日志系统
	sqlite3_close(db);
	return 0;

}
